﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using GeoAPI.Geometries;
using YJKRevitBase.Algorithm;
using YJKRevitBase.TopologySuite;
using YJKRevitKernel.RevitTopologySuite;
using YJKRevitDimensionText.VerticalAutoDim.GeoModel;

namespace YJKRevitDimensionText.VerticalAutoDim.GeoAlgorithm
{
	internal class GeoAABB : AABBDATA
	{
		public Envelope AABB
		{
			get
			{
				return this.aabb;
			}
		}

		public IPlanarGeo IPlanarGeo
		{
			get
			{
				return this._iPlanarGeo;
			}
		}

		public object Data
		{
			get
			{
				return this._data;
			}
		}

		public IList<RevitPolygonDataBean> ArrayBoundaryPolygon { get; private set; }

		public IList<RevitPolygonDataBean> ArrayBoundaryPolygonClippedResult { get; private set; }

		public GeoAABB(IPlanarGeo iPlanarGeo, object data = null)
		{
			this._iPlanarGeo = iPlanarGeo;
			this._data = data;
			this.aabb = new Envelope(this.IPlanarGeo.Min2DPointECS.X, this.IPlanarGeo.Max2DPointECS.X, this.IPlanarGeo.Min2DPointECS.Y, this.IPlanarGeo.Max2DPointECS.Y);
			this.ArrayBoundaryPolygon = new List<RevitPolygonDataBean>(1);
			RevitPolygonDataBean item = new RevitPolygonDataBean(CurveLoop.Create(Utility.CreateRectBoundaryCvsInEcs(this.IPlanarGeo.Min2DPointECS, this.IPlanarGeo.Max2DPointECS)), null, 3);
			this.ArrayBoundaryPolygon.Add(item);
			base.AppendAABBData(this.IPlanarGeo.Min2DPointECS.X, this.IPlanarGeo.Min2DPointECS.Y);
			base.AppendAABBData(this.IPlanarGeo.Max2DPointECS.X, this.IPlanarGeo.Max2DPointECS.Y);
			this.ArrayBoundaryPolygonClippedResult = new List<RevitPolygonDataBean>(this.ArrayBoundaryPolygon);
		}

		public bool Intersect(GeoAABB geoAABBOther, BooleanOperatorKindEnum type)
		{
			try
			{
				IList<RevitPolygonDataBean> lstPolygonThisCalc = new List<RevitPolygonDataBean>();
                //Action<RevitPolygonDataBean> ss9__0;
                //foreach (RevitPolygonDataBean item in this.ArrayBoundaryPolygonClippedResult)
                //{
                //    IList<RevitPolygonDataBean> list = new List<RevitPolygonDataBean>(1);
                //    list.Add(item);
                //    foreach (RevitPolygonDataBean polygonOther in geoAABBOther.ArrayBoundaryPolygon)
                //    {
                //        list = this.Intersect(list, polygonOther, 2);
                //    }
                //    IEnumerable<RevitPolygonDataBean> enumerable = list;
                //    Action<RevitPolygonDataBean> action;
                //    if ((action = ss9__0) == null)
                //    {
                //        action = (ss9__0 = delegate(RevitPolygonDataBean p)
                //        {
                //            lstPolygonThisCalc.Add(p);
                //        });
                //    }
                //    EnumerableExternsion.ForEach<RevitPolygonDataBean>(enumerable, action);
                //}
				this.ArrayBoundaryPolygonClippedResult = lstPolygonThisCalc;
				return true;
			}
			catch
			{
			}
			return false;
		}

		private IList<RevitPolygonDataBean> Intersect(IList<RevitPolygonDataBean> lstPolygon, RevitPolygonDataBean polygonOther, BooleanOperatorKindEnum type)
		{
			RevitPolygonBooleanOperater revitPolygonBooleanOperater = new RevitPolygonBooleanOperater();
			List<RevitPolygonDataBean> list = new List<RevitPolygonDataBean>();
			foreach (RevitPolygonDataBean revitPolygonDataBean in lstPolygon)
			{
				List<RevitOperationDataBean> list2 = null;
                revitPolygonBooleanOperater.TryGetBooleanResult(revitPolygonDataBean, polygonOther, type, out list2);
				if (list2 == null)
				{
					list.AddRange(new List<RevitPolygonDataBean>(0));
				}
				else
				{
					list.AddRange(list2.Cast<RevitPolygonDataBean>());
				}
			}
			return list;
		}

		public override string ToString()
		{
			return this.IPlanarGeo.Element.UniqueId.ToString();
		}

		public override int GetHashCode()
		{
			return this.ToString().GetHashCode();
		}

		public override bool Equals(object obj)
		{
			return this.GetHashCode() == obj.GetHashCode();
		}

		private readonly IPlanarGeo _iPlanarGeo;

		private readonly object _data;

		private readonly Envelope aabb;
	}
}
